using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;

namespace UpdateAuto
{
    public partial class TaskPanel : Panel
    {
        public List<TaskPanelItem> List = new List<TaskPanelItem>();
        private Point NextPanelPoint = new Point(0, 0);
        private int TaskPanelItemHeight = 70;
        public bool RemoveItemsWhenFinished = false;
        public bool RemoveItemsOnError = false;
        public bool AutoSizeForm = true;

        public TaskPanel()
        {
            InitializeComponent();
            this.TaskPanelItemHeight = new TaskPanelItem().Height;
        }

		/// <summary>
		/// Add a task to the panel.  The icon for 'processing' is not set until StartOperation is called
		/// </summary>
		/// <param name="op"></param>
		public void AddOperation(TaskPanelOperation op)
		{
			lock(this)
			{
				System.Diagnostics.Debug.WriteLine(String.Format("Adding panel with guid {0} for task {1}", op.Guid, op.Text));
				// add the item to the end of the form
				TaskPanelItem p = new TaskPanelItem(op);
				op.Status = TaskStatus.Waiting;
				p.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
				p.Location = NextPanelPoint;
				p.Width = this.Width - 30;
				this.Controls.Add(p);
				List.Add(p);

                if (AutoSizeForm && this.List.Count > 1)	// && this.Parent is Form && (this.Parent as Form).WindowState != FormWindowState.Minimized)
                {
                    // increase the size of the form
                    this.Parent.Height = Math.Min(550, 80 + TaskPanelItemHeight * this.List.Count);//this.Parent.Height + TaskPanelItemHeight);
                }
                NextPanelPoint.Y += TaskPanelItemHeight;
            }
        }

		delegate void StartOperationDelegate(string Guid);
		public void StartOperation(string Guid)
		{
			if(this.InvokeRequired)
			{
				Invoke(new StartOperationDelegate(this.StartOperation), new object[] { Guid});
				return;
			} 
			lock(this)
			{
				TaskPanelItem tp = (this.Controls["pnl" + Guid.Replace("-", "")] as TaskPanelItem);
				if(tp == null)
				{
					System.Diagnostics.Debug.WriteLine("Error task panel item not found for guid " + Guid);
					return;
				}
				tp.op.Status = TaskStatus.Running;
				tp.pictureBox1.Image = this.imageList1.Images[0];
				tp.progressBar1.Visible = true;
			}
		}

        delegate void EndOperationDelegate(string Guid, Exception ex);
        public void EndOperation(string Guid, Exception ex)
        {
            if (this.InvokeRequired)
            {
                Invoke(new EndOperationDelegate(this.EndOperation), new object[] { Guid, ex });
                return;
            }
            lock (this)
            {
                System.Diagnostics.Debug.WriteLine(String.Format("Removing panel with guid {0}", Guid));

                TaskPanelItem tp = (this.Controls["pnl" + Guid.Replace("-", "")] as TaskPanelItem);
                if (tp == null)
                {
                    System.Diagnostics.Debug.WriteLine("Error task panel item not found for guid " + Guid);
                    return;
                }
                tp.progressBar1.Visible = false;

                if (ex == null)	// set the icon to complete
                {
                    tp.op.Status = TaskStatus.Success;
                    tp.pictureBox1.Image = this.imageList1.Images[1];
                    tp.lblStatus.Text = "Complete";
                }
                else
                {
                    tp.op.Status = TaskStatus.Failed;
                    tp.pictureBox1.Image = this.imageList1.Images[2];
                    tp.lblStatus.Text = ex.Message;
                }

                if (!this.RemoveItemsWhenFinished)	// leave the task as it is
                    return;
                else if (!this.RemoveItemsOnError && ex != null)	// there is an error, and the task should not be removed.
                    return;

                // remove from the array list
                TaskPanelItem itemToRemove = null;
                int i = 0;	// store the position of the removed item, so we can move all items below, up one position
                foreach (TaskPanelItem item in List)
                {
                    i++;
                    if (item.op.Guid == Guid)
                    {
                        itemToRemove = item;
                        break;
                    }
                }
                if (itemToRemove != null)
                {
                    List.Remove(itemToRemove);
                    i--;
                }

                // remove the panel from the user interface
                Control ToRemove = null;
                foreach (Control c in this.Controls)
                {
                    if (c.Name == "pnl" + Guid.Replace("-", ""))
                    {
                        ToRemove = c;
                        break;
                    }
                }
                if (ToRemove != null)
                    this.Controls.Remove(ToRemove);

                // decrement the next panel point
                NextPanelPoint.Y -= TaskPanelItemHeight;

                // move items below up one position.  "i" holds the index of the panel to start moving up
                for (int j = i; j < List.Count; j++)
                {
                    string pnlName = "pnl" + List[j].op.Guid.Replace("-", "");
                    if (this.Controls[pnlName] == null)
                        continue;
                    else
                        this.Controls[pnlName].Top -= TaskPanelItemHeight;
                }
            }
        }

        delegate void ProgressChangedDelegate(string Guid, int ProgressPercentage, string Message);
        public void ProgressChanged(string Guid, int ProgressPercentage, string Message)
        {
            if (this.InvokeRequired)
            {
                Invoke(new ProgressChangedDelegate(this.ProgressChanged), new object[] { Guid, ProgressPercentage, Message });
                return;
            }
            string ControlName = "pnl" + Guid.Replace("-", "");
            if (this.Controls[ControlName] == null)
                return;
            TaskPanelItem item = this.Controls[ControlName] as TaskPanelItem;
            item.lblStatus.Text = Message;
            if (ProgressPercentage > 0 && ProgressPercentage < item.progressBar1.Maximum)
            {
                item.progressBar1.Value = ProgressPercentage;
                item.progressBar1.Visible = (Message.ToLower().IndexOf("waiting") < 0);
            }
        }
    }
}
